using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using HuaRongDaoGame.Models;

namespace HuaRongDaoGame.Services
{
    /// <summary>
    /// 游戏提示服务
    /// </summary>
    public class HintService
    {
        /// <summary>
        /// 获取下一步移动建议
        /// </summary>
        public static HintResult GetNextMoveHint(GameBoard gameBoard)
        {
            if (gameBoard == null || gameBoard.Blocks.Count == 0)
                return null;

            // 找到曹操方块（最大的方块）
            var caoBlock = gameBoard.Blocks.FirstOrDefault(b => b.IsCaoCao);
            if (caoBlock == null)
                return null;

            // 分析所有可能的移动
            var allPossibleMoves = new List<HintResult>();

            foreach (var block in gameBoard.Blocks)
            {
                var possibleMoves = gameBoard.GetPossibleMoves(block);
                foreach (var move in possibleMoves)
                {
                    var hint = new HintResult
                    {
                        Block = block,
                        TargetX = move.X,
                        TargetY = move.Y,
                        Priority = CalculateMovePriority(block, move, caoBlock, gameBoard)
                    };
                    allPossibleMoves.Add(hint);
                }
            }

            // 按优先级排序并返回最佳移动
            if (allPossibleMoves.Count > 0)
            {
                allPossibleMoves.Sort((a, b) => b.Priority.CompareTo(a.Priority));
                return allPossibleMoves[0];
            }

            return null;
        }

        /// <summary>
        /// 计算移动优先级
        /// </summary>
        private static int CalculateMovePriority(Block block, Point target, Block caoBlock, GameBoard gameBoard)
        {
            int priority = 0;

            // 如果是曹操方块，给予最高优先级
            if (block.IsCaoCao)
            {
                priority += 1000;
                
                // 如果移动朝向出口，给予额外优先级
                if (target.X >= 1 && target.Y >= 3) // 出口区域
                {
                    priority += 500;
                }
            }

            // 如果移动能释放曹操的路径，给予高优先级
            if (IsBlockingCaoCao(block, caoBlock))
            {
                priority += 800;
            }

            // 如果移动能创建更多空间，给予中等优先级
            if (CreatesMoreSpace(block, target, gameBoard))
            {
                priority += 300;
            }

            // 如果移动朝向棋盘中心，给予低优先级
            if (IsMovingTowardCenter(block, target))
            {
                priority += 100;
            }

            // 避免重复移动（如果方块刚移动过）
            if (IsRecentMove(block, gameBoard))
            {
                priority -= 200;
            }

            return priority;
        }

        /// <summary>
        /// 检查方块是否阻挡曹操
        /// </summary>
        private static bool IsBlockingCaoCao(Block block, Block caoBlock)
        {
            // 检查方块是否在曹操的路径上
            if (caoBlock.Y >= 3) // 曹操在出口附近
            {
                return block.Y >= 3 && block.X >= 1;
            }
            return false;
        }

        /// <summary>
        /// 检查移动是否能创造更多空间
        /// </summary>
        private static bool CreatesMoreSpace(Block block, Point target, GameBoard gameBoard)
        {
            // 简单的空间分析：检查移动后是否释放了更多格子
            var currentOccupied = GetOccupiedCells(block);
            var targetOccupied = GetOccupiedCells(block, target.X, target.Y);
            
            // 如果移动后占用的格子更少，说明创造了空间
            return targetOccupied.Count < currentOccupied.Count;
        }

        /// <summary>
        /// 检查是否朝向中心移动
        /// </summary>
        private static bool IsMovingTowardCenter(Block block, Point target)
        {
            var centerX = GameBoard.BOARD_WIDTH / 2;
            var centerY = GameBoard.BOARD_HEIGHT / 2;
            
            var currentDistance = Math.Abs(block.X - centerX) + Math.Abs(block.Y - centerY);
            var targetDistance = Math.Abs(target.X - centerX) + Math.Abs(target.Y - centerY);
            
            return targetDistance < currentDistance;
        }

        /// <summary>
        /// 检查是否是最近的移动
        /// </summary>
        private static bool IsRecentMove(Block block, GameBoard gameBoard)
        {
            if (gameBoard.MoveHistory.Count == 0)
                return false;

            var lastMove = gameBoard.MoveHistory[gameBoard.MoveHistory.Count - 1];
            return lastMove.BlockId == block.Id;
        }

        /// <summary>
        /// 获取方块占用的格子
        /// </summary>
        private static List<Point> GetOccupiedCells(Block block, int? x = null, int? y = null)
        {
            var cells = new List<Point>();
            var blockX = x ?? block.X;
            var blockY = y ?? block.Y;

            for (int i = 0; i < block.Width; i++)
            {
                for (int j = 0; j < block.Height; j++)
                {
                    cells.Add(new Point(blockX + i, blockY + j));
                }
            }

            return cells;
        }

        /// <summary>
        /// 获取完整的解决方案提示
        /// </summary>
        public static List<HintResult> GetSolutionHint(GameBoard gameBoard, int maxSteps = 10)
        {
            var solution = new List<HintResult>();
            var currentBoard = gameBoard.GetSnapshot();
            
            for (int i = 0; i < maxSteps; i++)
            {
                var hint = GetNextMoveHint(gameBoard);
                if (hint == null)
                    break;

                solution.Add(hint);
                
                // 模拟移动
                if (gameBoard.MoveSelectedBlock(hint.TargetX, hint.TargetY))
                {
                    // 检查是否胜利
                    if (gameBoard.IsGameWon())
                        break;
                }
                else
                {
                    break;
                }
            }

            // 恢复原始状态
            gameBoard.RestoreFromSnapshot(currentBoard);
            
            return solution;
        }
    }

    /// <summary>
    /// 提示结果
    /// </summary>
    public class HintResult
    {
        /// <summary>
        /// 要移动的方块
        /// </summary>
        public Block Block { get; set; }

        /// <summary>
        /// 目标X坐标
        /// </summary>
        public int TargetX { get; set; }

        /// <summary>
        /// 目标Y坐标
        /// </summary>
        public int TargetY { get; set; }

        /// <summary>
        /// 移动优先级
        /// </summary>
        public int Priority { get; set; }

        /// <summary>
        /// 提示描述
        /// </summary>
        public string Description
        {
            get
            {
                if (Block == null)
                    return "无法提供提示";

                var direction = GetDirectionDescription();
                return string.Format("建议移动 {0} 方块 {1}", Block.Name, direction);
            }
        }

        /// <summary>
        /// 获取方向描述
        /// </summary>
        private string GetDirectionDescription()
        {
            if (Block == null)
                return "";

            var deltaX = TargetX - Block.X;
            var deltaY = TargetY - Block.Y;

            if (deltaX > 0) return "向右";
            if (deltaX < 0) return "向左";
            if (deltaY > 0) return "向下";
            if (deltaY < 0) return "向上";

            return "原地";
        }
    }
} 